Conversation
Static top-level import compiled to synchronous require() in CJS, which
triggered fs.readFileSync on the .wasm binary at module load time. fs
does not exist in browser environments, so all WASM functions were
undefined when called from sdk-core.
Mirror the ECDSA DKG pattern (ecdsa-dkls/dkg.ts):
- Remove static top-level import of @bitgo/wasm-mps
- Add wasmMps field with optional constructor injection for DI
- Add private loadWasmMps() that lazily does await import('@bitgo/wasm-mps')
(bundler resolves to ESM in browser, CJS in Node — no typeof window
check needed as wasm-mps ships a single package with dual exports)
- Make initDkg() async; WASM is loaded once on first call
- All WASM calls go through getWasmMps() which throws if not loaded
- Add await to initDkg() calls in sdk-core/eddsaMPCv2.ts
- Update tests to await initDkg() and mark affected callbacks async
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TICKET: WCI-244
mohammadalfaiyazbitgo
approved these changes
Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
sdk-lib-mpc/src/tss/eddsa-mps/dkg.ts used a static top-level import:
import { ed25519_dkg_round0_process, ... } from '@bitgo/wasm-mps';TypeScript compiles this to a synchronous require() in CJS output. The CJS build of @bitgo/wasm-mps
calls fs.readFileSync(wasmPath) at module load time to initialise the WASM binary. fs does not exist in
the browser, so all three round functions are never initialised — causing silent undefined errors when
sdk-core attempts EdDSA MPCv2 key generation in a browser environment.
Fix
Mirrors the existing ECDSA DKG pattern (ecdsa-dkls/dkg.ts):
resolves this to the ESM build in browser and CJS in Node. No typeof window check is needed since
wasm-mps ships a single package with dual ESM/CJS exports (unlike dkls which has separate node/web
packages)
Why .mocharc.js needs experimental-wasm-modules
In tests, mocha uses require: 'tsx' which transforms TypeScript on-the-fly using esbuild in
transform-only mode. Unlike tsc, esbuild in this mode does not rewrite await import() to require() — it
leaves it as a native Node dynamic import. Node's native dynamic import uses the "import" export
condition, which resolves to the ESM build of wasm-mps. That ESM build contains import * as wasm from
"./wasm_mps_bg.wasm", which Node cannot handle without --experimental-wasm-modules.
Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
TICKET: WCI-244